#![allow(dead_code)]
use crate::domain::CountNum;
use crate::domain::RoleBean;
use crate::domain::UserBean;
use crate::domain::UserQueryRequest;
use crate::serviceimpl::init_db;
use crate::utils::encrypt_util::multi_sha1;
use crate::utils::password_util::generate_salt;
use crate::utils::string_util::is_digit;
use crate::utils::string_util::right_find_under_line;
use sqlx::Error;
use substring::Substring;

pub async fn activate_all_users(ids:Vec<i64>) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	let vecter_iterator = ids.iter();
	for user_id in vecter_iterator {
		let _ = users.activate_user(*user_id).await;
	}
	Ok(0)
}

pub async fn activate_user(id:i64) ->Result<u64, Error> {
	let app_state = init_db();
	app_state.await.context.users.activate_user(id).await
}

pub async fn add_user(user:UserBean) ->Result<u64, Error> {
	let salt = generate_salt().await.unwrap();
	let password = multi_sha1(user.clone().password,salt.clone(),3);
	let mut user = user.clone();
	user.salt = salt.clone();
	user.password = password;
	let app_state = init_db();
	app_state.await.context.users.add_user(user).await
}

pub async fn assign_roles_to_user(user_id:i64,role_ids:Vec<i64>) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	for role_id in role_ids.iter() {
		users.assign_role_to_user(user_id,*role_id).await.unwrap();
	}
	Ok(0)
}

pub async fn change_password_user(user:UserBean) ->Result<u64, Error> {
	let salt = generate_salt().await.unwrap();
	let mut user2 = user.clone();
	let encrpt = multi_sha1(user2.password,salt.clone(),3);
	user2.password = encrpt;
	user2.salt = salt.clone();
	let app_state = init_db();
	app_state.await.context.users.change_password_user(user2).await
}

pub async fn clone_all_users(ids:Vec<i64>) ->Result<u64, Error> {
	let vecter_iterator = ids.iter();
	for user_id in vecter_iterator {
		let _ = clone_user(*user_id).await;
	}
	Ok(0)
}

pub async fn clone_user(id:i64) ->Result<u64, Error> {
	let mut user = find_user_by_id(id).await.unwrap();
	let user_name = find_user_indexed_name(user.user_name).await.unwrap();
	user.user_name = user_name;
	add_user(user).await
}

pub async fn count_search_users_by_fields_records(user_query_request:UserQueryRequest) ->Result<CountNum, Error> {
	let app_state = init_db();
	app_state.await.context.users.count_search_users_by_fields_records(user_query_request).await
}

pub async fn delete_all_users(ids:Vec<i64>) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	let vecter_iterator = ids.iter();
	for user_id in vecter_iterator {
		let _ = users.delete_user(*user_id).await;
	}
	Ok(0)
}

pub async fn delete_user(id:i64) ->Result<u64, Error> {
	let app_state = init_db();
	app_state.await.context.users.delete_user(id).await
}

pub async fn find_user_by_id(id:i64) ->Result<UserBean, Error> {
	let app_state = init_db();
	app_state.await.context.users.find_user_by_id(id).await
}

pub async fn find_user_by_user_name(user_name:String) ->Result<UserBean, Error> {
	let app_state = init_db();
	app_state.await.context.users.find_user_by_user_name(user_name).await
}

pub async fn find_user_shadow_by_user_name(user_name:String) ->Result<UserBean, Error> {
	let app_state = init_db();
	app_state.await.context.users.find_user_shadow_by_user_name(user_name).await
}

pub async fn list_active_user_roles_using_user_id(user_id:i64) ->Result<Vec<RoleBean>, Error> {
	let app_state = init_db();
	app_state.await.context.roles.list_active_user_roles_using_user_id(user_id).await
}

pub async fn list_active_users() ->Result<Vec<UserBean>, Error> {
	let app_state = init_db();
	app_state.await.context.users.list_active_users().await
}

pub async fn list_all_users() ->Result<Vec<UserBean>, Error> {
	let app_state = init_db();
	app_state.await.context.users.list_all_users().await
}

pub async fn list_available_active_user_roles_using_user_id(user_id:i64) ->Result<Vec<RoleBean>, Error> {
	let app_state = init_db();
	let roles = &app_state.await.context.roles;
	let mut all_roles = roles.list_active_roles().await.unwrap();
	let current_roles = list_active_user_roles_using_user_id(user_id).await.unwrap();

	all_roles.retain(|role| !current_roles.contains(role));
	Ok(all_roles)
}

pub async fn register_user(user:UserBean) ->Result<u64, Error> {
	let salt = generate_salt().await.unwrap();
	let password = multi_sha1(user.clone().password,salt.clone(),3);
	let mut user = user.clone();
	user.salt = salt.clone();
	user.password = password;
	let app_state = init_db();
	app_state.await.context.users.register_user(user).await
}

pub async fn revoke_roles_from_user(user_id:i64,role_ids:Vec<i64>) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	for role_id in role_ids.iter() {
		users.revoke_role_from_user(user_id,*role_id).await.unwrap();
	}
	Ok(0)
}

pub async fn search_users_by_fields(user_query_request:UserQueryRequest) ->Result<Vec<UserBean>, Error> {
	let app_state = init_db();
	app_state.await.context.users.search_users_by_fields(user_query_request).await
}

pub async fn search_users_by_fields_by_page(user_query_request:UserQueryRequest) ->Result<Vec<UserBean>, Error> {
	let app_state = init_db();
	app_state.await.context.users.search_users_by_fields_by_page(user_query_request).await
}

pub async fn soft_delete_all_users(ids:Vec<i64>) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	let vecter_iterator = ids.iter();
	for user_id in vecter_iterator {
		let _ = users.soft_delete_user(*user_id).await;
	}
	Ok(0)
}

pub async fn soft_delete_user(id:i64) ->Result<u64, Error> {
	let app_state = init_db();
	app_state.await.context.users.soft_delete_user(id).await
}

pub async fn toggle_one_user(id:i64) ->Result<u64, Error> {
	let app_state = init_db();
	let users = &app_state.await.context.users;
	let user = users.find_user_by_id(id).await.unwrap();
	if user.active == false {
		let _ = users.toggle_user(id).await;
	} else {
		let count = users.count_active_user_records().await.unwrap();
		if count.count_num > 1 {
			let _ = users.toggle_user(id).await;
		}
	}
	Ok(0)
}

pub async fn count_active_user_records() ->Result<CountNum, Error> {
	let app_state = init_db();
	app_state.await.context.users.count_active_user_records().await
}

pub async fn toggle_user(id:i64) ->Result<u64, Error> {
	let app_state = init_db();
	app_state.await.context.users.toggle_user(id).await
}

pub async fn update_user(user:UserBean) ->Result<u64, Error> {
	let app_state = init_db();
	app_state.await.context.users.update_user(user).await
}

pub async fn find_user_indexed_name(name:String) ->Result<String, Error> {
	let mut short_name = name.clone();
	if name.contains("_") && is_digit(name.substring(right_find_under_line(name.clone())+1,name.chars().count()).to_string()) {
		short_name = name.substring(0,right_find_under_line(name.clone())).to_string();
	}

	let app_state = init_db();
	let users = app_state.await.context.users.find_user_indexed_name(short_name.clone()).await.unwrap();

	let mut index_num = 1;
	for user in users {
		let name2 = user.user_name;
		if name2.contains("_") && is_digit(name2.substring(right_find_under_line(name2.clone())+1,name2.chars().count()).to_string()) {
			let index = name2.substring(right_find_under_line(name2.clone())+1,name2.chars().count()).parse::<i32>().unwrap();
			if index >= index_num {
				index_num = index + 1;
			}
		}
	}

	let index_name = short_name.clone() + "_" + &index_num.to_string();
	Ok(index_name)
}
